package com.Java.train.business.service.daily.Impl;

import cn.hutool.core.date.DateUtil;
import com.Java.train.business.entity.*;
import com.Java.train.business.enums.SeatColEnum;
import com.Java.train.business.service.TrainCarriageService;
import com.Java.train.common.response.CommonResp;
import com.Java.train.business.entity.DTO.DailyTrainCarriageDTO;
import com.Java.train.business.req.daily.DailyTrainCarriageQueryReq;
import com.Java.train.common.exception.BusniessException;
import com.Java.train.common.exception.BusniessExceptionEnum;
import com.Java.train.common.response.PageResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.Java.train.business.mapper.DailyTrainCarriageMapper;
import com.Java.train.business.service.daily.DailyTrainCarriageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import com.Java.train.common.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.date.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
* 每日车厢 服务实现类
*
* @author luomoxingchen
* @since 2024-09-24
*/
@Service
public class DailyTrainCarriageServiceImpl extends ServiceImpl<DailyTrainCarriageMapper, DailyTrainCarriage> implements DailyTrainCarriageService {

    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainCarriageService.class);

    @Autowired
    DailyTrainCarriageMapper dailyTrainCarriageMapper;

    @Resource
    private TrainCarriageService trainCarriageService;

    @Override
    public PageResp<DailyTrainCarriageDTO> queryList(DailyTrainCarriageQueryReq dailyTrainCarriageQueryReq){
        // 1.获取当前用户id信息
        //        Long id = LoginMemberContext.getId();
        String trainCode = dailyTrainCarriageQueryReq.getTrainCode();
        Date date = dailyTrainCarriageQueryReq.getDate();
        // 2.查询数据库中是否存在当前信息（id）
        LOG.info("查询页码：{}", dailyTrainCarriageQueryReq.getPage());
        LOG.info("每页条数：{}", dailyTrainCarriageQueryReq.getSize());
        PageHelper.startPage(dailyTrainCarriageQueryReq.getPage(),dailyTrainCarriageQueryReq.getSize());

        // 2.1 判重并筛选
        List<DailyTrainCarriage> dailyTrainCarriages = null;
        if(StrUtil.isNotBlank(trainCode) || ObjectUtil.isNotEmpty(date)){
            dailyTrainCarriages = getDailyCarriageByCondition(trainCode, date);
        }else {
            dailyTrainCarriages = list();
        }

        if(dailyTrainCarriages == null || CollUtil.isEmpty(dailyTrainCarriages)){
            // 返回空列表
            return new PageResp<DailyTrainCarriageDTO>();
//            throw new BusniessException(BusniessExceptionEnum.MEMBER_PASSENGER_NOT_EXITS);
        }
        // 2.2 填充座位数
        for (DailyTrainCarriage trainCarriage : dailyTrainCarriages) {
            trainCarriage.setSeatCount(trainCarriage.getLineCount() * trainCarriage.getColCount());
        }

        // 3 分析分页信息
        // 3.1 获取分页总条数和页数
        PageInfo<DailyTrainCarriage> pageInfo = new PageInfo<>(dailyTrainCarriages);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        // 3.2 转为封装后的返回值并封装到分页返回值中
        List<DailyTrainCarriageDTO> list = BeanUtil.copyToList(dailyTrainCarriages, DailyTrainCarriageDTO.class);
        PageResp<DailyTrainCarriageDTO> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(list);
        // 4.返回查询到的信息
        return pageResp;
    }

    @Override
    public CommonResp<Object> modify(DailyTrainCarriage dailyTrainCarriage) {
        Long id = dailyTrainCarriage.getId();
        DateTime dateTime = DateTime.now();
        if(ObjectUtil.isNull(id)){
            // 自动生成列数和总座位数
            List<SeatColEnum> colEnums = SeatColEnum.getColsByType(dailyTrainCarriage.getSeatType());
            dailyTrainCarriage.setColCount(colEnums.size());
            dailyTrainCarriage.setSeatCount(dailyTrainCarriage.getColCount() * dailyTrainCarriage.getLineCount());

            // 判重
            if(ObjectUtil.isNotEmpty(getCarriageByUnique(dailyTrainCarriage.getTrainCode(), dailyTrainCarriage.getIdx(), dailyTrainCarriage.getDate()))){
                throw new BusniessException(BusniessExceptionEnum.BUSINESS_CARRIAGE_ALREADY_EXITS);
            }

            dailyTrainCarriage.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyTrainCarriage.setCreateTime(dateTime);
            dailyTrainCarriage.setUpdateTime(dateTime);
            boolean save = save(dailyTrainCarriage);
            return new CommonResp<>(save);
        } else {
            dailyTrainCarriage.setUpdateTime(dateTime);
            boolean update = updateById(dailyTrainCarriage);
            return new CommonResp<>(update);
        }
    }

    @Override
    public CommonResp<Object> remove(String ids) {
        if(StrUtil.isNotEmpty(ids)){
            String[] array = ids.split(",");
            if(!CollectionUtils.isEmpty(Arrays.asList(array))) {
                return new CommonResp<>(dailyTrainCarriageMapper.deleteBatchIds(Arrays.asList(array)));
            }
        }
        return new CommonResp<>(Collections.EMPTY_LIST);
    }

    @Override
    public List<DailyTrainCarriage> genDaily(Date date, String trainCode) {
        LOG.info("生成日期为[{}]车次编号为[{}]的车厢数据开始", DateUtil.formatDate(date), trainCode);
        // 1.查询是否存在火车
        LambdaQueryWrapper<TrainCarriage> wrapper = new LambdaQueryWrapper<>();
        List<TrainCarriage> carriages = trainCarriageService.list(wrapper.eq(TrainCarriage::getTrainCode, trainCode)
                .orderBy(true, true, TrainCarriage::getIdx));
        if(CollUtil.isEmpty(carriages)){
            LOG.info("没有火车车厢信息");
            return Collections.EMPTY_LIST;
        }

        // 2.复制生成dailyTrain
        List<DailyTrainCarriage> dailyTrainCarriages = BeanUtil.copyToList(carriages, DailyTrainCarriage.class);
        // 2.1 删除之前生成的火车车厢(直接删一个车厢）
        LambdaQueryWrapper<DailyTrainCarriage> dailyWrapper = new LambdaQueryWrapper<>();
        remove(dailyWrapper.eq(DailyTrainCarriage::getTrainCode, trainCode).eq(DailyTrainCarriage::getDate, date));

        DateTime dateTime = DateTime.now();
        for (DailyTrainCarriage dailyCarriage : dailyTrainCarriages) {
            // 2.2 生成每日车厢
            dailyCarriage.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyCarriage.setCreateTime(dateTime);
            dailyCarriage.setUpdateTime(dateTime);
            dailyCarriage.setDate(date);
            save(dailyCarriage);
        }
        LOG.info("生成日期为[{}]车次编号为[{}]的车厢数据结束", DateUtil.formatDate(date), trainCode);
        return dailyTrainCarriages;
    }

    // 条件筛选
    private List<DailyTrainCarriage> getDailyCarriageByCondition(String trainCode, Date date) {
        LambdaQueryWrapper<DailyTrainCarriage> wrapper = new LambdaQueryWrapper<>();
        List<DailyTrainCarriage> list = null;
        if(StrUtil.isNotBlank(trainCode) && ObjectUtil.isEmpty(date)){
            list = list(wrapper.eq(DailyTrainCarriage::getTrainCode, trainCode).orderBy(true, true, DailyTrainCarriage::getTrainCode));
        } else if(ObjectUtil.isNotEmpty(date) && StrUtil.isBlank(trainCode)){
            list = list(wrapper.eq(DailyTrainCarriage::getDate, date).orderBy(true, true, DailyTrainCarriage::getDate));
        } else{
            list = list(wrapper.eq(DailyTrainCarriage::getTrainCode, trainCode).eq(DailyTrainCarriage::getDate, date).orderBy(true, true, DailyTrainCarriage::getDate, DailyTrainCarriage::getTrainCode));
        }
        return list;
    }

    // 通过唯一键校验查重
    private DailyTrainCarriage getCarriageByUnique(String trainCode, Integer idx, Date date) {
        LambdaQueryWrapper<DailyTrainCarriage> wrapper = new LambdaQueryWrapper<>();
        DailyTrainCarriage one = getOne(wrapper.eq(DailyTrainCarriage::getTrainCode, trainCode).eq(DailyTrainCarriage::getIdx, idx).eq(DailyTrainCarriage::getDate, date));
        return one;
    }

     /**
      * @param
      * @return
      * @Description: 查询座位等次对应所有车厢
      */
     public List<DailyTrainCarriage> selectCarriageBySeatType(Date date, String trainCode, String seatType){
         // 1、按座位等次筛出每日车厢
        LambdaQueryWrapper<DailyTrainCarriage> wrapper = new LambdaQueryWrapper<>();
         List<DailyTrainCarriage> trainCarriages = list(wrapper.eq(DailyTrainCarriage::getDate, date).eq(DailyTrainCarriage::getTrainCode, trainCode)
                 .eq(DailyTrainCarriage::getSeatType, seatType));

        return trainCarriages;
     }
}


